package com.nineclock.approve.service.impl;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.google.gson.JsonObject;
import com.nineclock.approve.pojo.ApproveDefinition;
import com.nineclock.approve.resolver.ProcessNodeResolver;
import com.nineclock.approve.resolver.ProcessNodeResolverFactory;
import com.nineclock.approve.service.ActivitiService;
import com.nineclock.approve.utils.ActivitiUtils;
import com.nineclock.common.utils.JsonUtils;
import org.activiti.bpmn.BpmnAutoLayout;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ActivitiServiceImpl implements ActivitiService {
    @Autowired
    RepositoryService repositoryService;

    // 删除流程定义
    @Override
    public void deleteProcessDefinition(String definitionId) {
        // 根据流程定义ID删除activiti中的数据
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey("process_" + definitionId)
                .singleResult();
        if (processDefinition != null) {
            repositoryService.deleteDeployment(processDefinition.getDeploymentId());
        }
    }

    @Override
    public void deployProcessToActiviti(ApproveDefinition definition) {
        // 构建BpmnModel
        BpmnModel bpmnModel = new BpmnModel();
        // 构建Process
        Process process = new Process();
        process.setId(ActivitiUtils.PROCESS_PREFIX +definition.getId());
        process.setName(definition.getName());
        // 创建流程节点(开始的节点,结束的节点,审核节点....)
        String flowJson = definition.getFlowJson();
        JSONArray jsonArray = JSONUtil.parseArray(flowJson);
        this.addNodeToProcess(jsonArray, process);
        //添加Process到BpmnModel中
        bpmnModel.addProcess(process);
        // 部署构建的审批流程到Activiti中
        repositoryService.createDeployment()
                .name(definition.getName())
                .addBpmnModel(definition.getName() + ".bpmn", bpmnModel)
                .deploy();

        //5. 自动布局BpmnModel
        new BpmnAutoLayout(bpmnModel).execute();

        //输出XML, 便于测试
        BpmnXMLConverter converter = new BpmnXMLConverter();
        byte[] bytes = converter.convertToXML(bpmnModel);

        System.out.println("-------> 转换BpmnModel为XML数据 .");
        System.out.println(new String(bytes));
        System.out.println("-------> XML文件转换并输出完毕 . ");

    }
// 添加不同的节点到process中
    private void addNodeToProcess(JSONArray jsonArray, Process process) {
        for (int i = 0; i < jsonArray.size(); i++) {
            // 当前节点
            JSONObject currNode = (JSONObject) jsonArray.get(i);
            JSONObject nextNode = null;
            //网关的条件并不是真正的节点
            if("cond".equals(currNode.getStr("type"))){
                continue;
            }
            // 获取下一个节点
            if (i < jsonArray.size() - 1) {
                nextNode = (JSONObject) jsonArray.get(i + 1);
            }
            // 传递当前节点和下一个节点,进行流程绘制,不同的节点类型调用的API不同,由Type来决定
            //TODO
            ProcessNodeResolver processNodeResolver = ProcessNodeResolverFactory.getInstance(currNode.getStr("type"));
            if (processNodeResolver != null) {
                processNodeResolver.addFlowNodeToActiviti(process, currNode, nextNode);
            }
        }
    }
}
